<?php


namespace app\controller\shop;


use app\model\User;
use app\services\RedisServices;
use app\services\SnapPayServices;
use app\services\UserServices;
use app\validate\shop\UserValidate;
use think\App;

class UserController extends ShopBaseController
{


	protected UserValidate $userValidate;

	protected UserServices $userServices;


	public function __construct (
		UserServices $userServices, UserValidate $userValidate
	) {
		$this->userValidate = $userValidate;
		$this->userServices = $userServices;
	}

	public function index () {

		$validateRes = (new UserValidate())->goSceneCheck('index');
		if ($validateRes) {
			return toast($validateRes);
		}

		return success((new RedisServices())->setting());
	}

	public function verify () {
		$validateRes = (new UserValidate())->goSceneCheck('verify');
		if ($validateRes) {
			//return toast($validateRes);
		}

		$userServices = app(UserServices::class);

		return success($userServices->verify($this->request));
	}


	public function pay () {
		$snapPayServices = new SnapPayServices();

		return success($snapPayServices->inAppPay());


	}


	protected function getCurrent ($id, $tier = 1, $type = true) {
		$list = [
			['id' => 1, 'name' => 'zhangsan', 'type' => 1],
			['id' => 2, 'name' => 'lisi', 'type' => 2],
			['id' => 3, 'name' => 'wangwu', 'type' => 1],
			['id' => 7, 'name' => '刘麻子', 'type' => 1],
			['id' => 9, 'name' => '长贵', 'type' => 1],
		];

		$currentIndex = array_search($id, array_column($list, 'id'));

		if ($currentIndex !== false) {
			$index = $type ? $currentIndex + $tier : $currentIndex - $tier;

			if (array_key_exists($index, $list)) {
				return $list[$index];
			}

			return false;
		}

		return false;
	}


	public function pays () {


		$level = [
			['id' => 1, 'grade' => 1, 'title' => '分销商', 'one_ratio' => 1, 'two_ratio' => 2, 'team_ratio' => 1],
			['id' => 2, 'grade' => 2, 'title' => '团队', 'one_ratio' => 2, 'two_ratio' => 4, 'team_ratio' => 2],
			['id' => 3, 'grade' => 3, 'title' => '合作人', 'one_ratio' => 3, 'two_ratio' => 6, 'team_ratio' => 3],
		];


		$uid = 133;

		//下单人
		$buyer = User::where('uid', ' = ', $uid)->field('uid,nickname,m_level,spread_uid')->find();
		//一级上线
		$one_spread = User::where('uid', ' = ', $buyer['spread_uid'])->field('uid,nickname,m_level,spread_uid')->find();
		$price = 100;

		if ($one_spread) {//一级上线是存在的
			//此时表示下单人的等级是普通会员,此时一级上线获得就是管理奖
			if ($buyer->m_level < $level[0]['grade']) {

				/**
				 * 基本逻辑
				 * 下单人的等级是普通用户
				 * 此时一级用户的等级只有大于等于分销商才能或得到佣金
				 *      1.一级获得是管理奖(管理奖分,分销管理奖,团队管理奖,合伙人管理奖)
				 *      2.二级获得什么奖励?
				 *          a).一级是合伙人
				 *                 二级 === 一级 二级才能获得二级分佣
				 *                 无人获得管理奖了
				 *
				 *          b).一级是团队
				 *                 二级 === 一级  二级获得二级分佣，存在已合伙人的等级上线 获得管理奖
				 *
				 *                 二级 > 一级   二级只能是合伙人,二级获得合伙人管理奖
				 *
				 *                 二级 < 一级   二级没有奖励,存在一个比一级等级高的上级(也就是合伙人等级)获得合伙人奖励
				 *
				 *          c).一级是分销商
				 *
				 *                二级 === 一级   二级获得二级分佣,存在一个团队等级的上线 和 合伙人等级的上线获得 管理奖
				 *
				 *                 二级 > 一级    二级可能是团队或者合伙人
				 *                               如果二级是团队,则二级获得团队管理奖, 还存在一个比二级等级高的 合伙人等级的上线获得 合伙人管理奖
				 *                               如果二级是合伙人,则二级获得合伙人管理奖
				 *
				 *                  二级 < 一级   二级没有奖励,存在比一级等级高,即团队或者合伙人获得管理奖
				 *
				 *
				 */

				for ($i = 0; $i < count($level); $i++) {
					$current_level = $level[$i]['grade'];
					$manage_brokerage = bcmul($price, bcdiv($level[$i]['team_ratio'], 100, 2), 2);
					if ($one_spread->m_level === $current_level) {//获得对应等级的管理奖
						addErrorLog('一级上线：' . $one_spread->nickname . '获得:' . $level[$i]['title'] . '管理奖' . $manage_brokerage);
						if ($one_spread->spread_uid) {
							//二级上线存在
							$two_spread = User::where('uid', ' = ', $one_spread['spread_uid'])->field('uid,nickname,m_level,spread_uid')->find();
							if ($two_spread) {
								if ($two_spread->m_level === $one_spread->m_level) {
									//二级等级等于一级等级,此时二级获得二级分佣
									//存在一个上线获得团队管理奖，存在一个上线获得合伙人管理奖
									$two_brokerage = bcmul($price, bcdiv($level[$i]['two_ratio'], 100, 2), 2);
									addErrorLog('二级上线：' . $two_spread->nickname . '获得二级佣金:' . $two_brokerage);
									$index = array_search($two_spread->m_level, array_column($level, 'grade'));
									$this->getTeamBroerage($uid, $level, $index);
								} else if ($two_spread->m_level > $one_spread->m_level) {//二级的等级大于一级等级，二级获得管理奖金
									//二级获得什么类型的管理奖 团队或者是合伙人
									$index = array_search($two_spread->m_level, array_column($level, 'grade'));
									$team_level = $level[$index];
									$team_brokerage = bcmul($price, bcdiv($team_level['team_ratio'], 100, 2), 2);
									addErrorLog($two_spread['nickname'] . '获得:' . $team_level['title'] . '管理奖' . $team_brokerage);

									//检测是否存在比二级等级高的上线存在,如存在则计算更高等级的管理奖
									$this->getTeamBroerage($uid, $level, $index);

								} else if ($two_spread->m_level < $one_spread->m_level) {
									//检测是否存在比一级等级高的上线存在,如存在则计算更高等级的管理奖
									$index = array_search($one_spread->m_level, array_column($level, 'grade'));
									$this->getTeamBroerage($uid, $level, $index);
								}
							}
						}
					}
				}
			} else {//下单人的等级至少是分销商等级
				/**
				 * 基本逻辑
				 * 下单人的等级至少是分销商等级
				 *
				 * 下单人的等级是合伙人
				 *      1.一级 === 下单人的等级  一级获得一级分销奖励
				 *      2.二级 === 一级     二级获得二级分销
				 *      3.二级 > 一级       不存在
				 *
				 * 下单人的等级是团队
				 *      1.一级 等于 下单人的等级
				 *          一级获得一级分销奖励
				 *          二级 ?
				 *              二级 = 一级  二级获得二级分佣奖励 ,存在一个比二级等级高的上线获得合伙人管理奖
				 *              二级 > 一级  二级（只能是合伙人） 二级获得合伙人管理奖
				 *
				 *      2.一级 大于 下单人的等级,（一级只能是合伙人）
				 *          一级获得合伙人管理奖
				 *
				 *          二级?
				 *              二级 = 一级  二级获得二级分佣奖励
				 *              二级 > 一级  不存在
				 *
				 *
				 * 下单人的等级是分销商
				 *      1. 一级 等于 下单人的等级
				 *          一级获得一级分销奖励
				 *
				 *          二级?
				 *              二级 = 一级 二级获得二级分佣,存在比二级等级高的上线（团队/合伙人） 获得管理奖
				 *              二级 > 一级 二级获得管理奖,
				 *                  二级是团队,获得团队管理奖,还存在一个比二级等级高(合伙人)的上线获得管理奖
				 *                  二级是合伙人,二级获得合伙人管理奖
				 *
				 *      2.一级 大于 下单人等级
				 *            一级获得管理奖
				 *             一级是团队,获得团队管理奖
				 *            二级?
				 *                  二级 = 一级   二级获得二级分佣,存在一个比二级等级高的上线获得管理奖
				 *                  二级 > 一级   二级获得合伙人管理奖
				 *
				 *
				 *             一级是合伙人,获得合伙人管理奖
				 *                  二级 = 一级  二级获得二级分佣(二级只能是合伙人)
				 *                  二级 > 一级  不存在
				 */

				for ($i = 0; $i < count($level); $i++) {

					$buyer_level = $buyer->m_level;
					$current_level = $level[$i]['grade'];

					if ($current_level == $buyer_level) {//分销商开始,会员过滤掉

						if ($one_spread->m_level == $current_level) {//一级等级等于下单人等级

							//一级获得分销佣金
							$one_brokerage = bcmul($price, bcdiv($level[$i]['one_ratio'], 100, 2), 2);
							addErrorLog('一级上线' . $one_spread['nickname'] . '获得:' . $level[$i]['title'] . '一级分佣' . $one_brokerage);
							if ($one_spread->spread_uid) {
								//二级上线存在
								$two_spread = User::where('uid', ' = ', $one_spread['spread_uid'])->field('uid,nickname,m_level,spread_uid')->find();
								if ($two_spread) {
									if ($two_spread->m_level == $one_spread->m_level) {//二级获得二级分佣
										$two_brokerage = bcmul($price, bcdiv($level[$i]['two_ratio'], 100, 2), 2);
										addErrorLog('二级上线：' . $two_spread->nickname . '获得二级佣金:' . $two_brokerage);
										//检测是否存在比二级等级高的上线存在,存在则获得团队管理奖
										$index = array_search($two_spread->m_level, array_column($level, 'grade'));
										$this->getTeamBroerage($uid, $level, $index);
									} else if ($two_spread->m_level > $one_spread->m_level) {//二级获得管理奖
										$index = array_search($two_spread->m_level, array_column($level, 'grade'));
										$team_level = $level[$index];
										$team_brokerage = bcmul($price, bcdiv($team_level['team_ratio'], 100, 2), 2);
										addErrorLog($two_spread['nickname'] . '获得:' . $team_level['title'] . '管理奖' . $team_brokerage);
										//检测是否存在比二级等级高的上线存在,如存在则计算更高等级的管理奖
										$index = array_search($two_spread->m_level, array_column($level, 'grade'));
										$this->getTeamBroerage($uid, $level, $index);
									}
								}
							}

						} else if ($one_spread->m_level > $current_level) {//一级等级大于下单等级
							//一级获得是管理奖
							$index = array_search($one_spread->m_level, array_column($level, 'grade'));
							$team_level = $level[$index];

							$team_brokerage = bcmul($price, bcdiv($team_level['team_ratio'], 100, 2), 2);
							addErrorLog($one_spread['nickname'] . '获得:' . $team_level['title'] . '管理奖' . $team_brokerage);
							//二级获得什么?
							if ($one_spread->spread_uid) {
								//二级上线存在
								$two_spread = User::where('uid', ' = ', $one_spread['spread_uid'])->field('uid,nickname,m_level,spread_uid')->find();
								if ($two_spread) {
									if ($two_spread->m_level == $one_spread->m_level) {//二级获得二级分佣
										$two_brokerage = bcmul($price, bcdiv($level[$i]['two_ratio'], 100, 2), 2);
										addErrorLog('二级上线：' . $two_spread->nickname . '获得二级佣金:' . $two_brokerage);
										//检测是否存在比二级等级高的上线存在,存在则获得团队管理奖
										$index = array_search($two_spread->m_level, array_column($level, 'grade'));
										$this->getTeamBroerage($uid, $level, $index);
									} else if ($two_spread->m_level > $one_spread->m_level) {//二级获得管理奖
										$index = array_search($two_spread->m_level, array_column($level, 'grade'));
										$team_level = $level[$index];
										$team_brokerage = bcmul($price, bcdiv($team_level['team_ratio'], 100, 2), 2);
										addErrorLog($two_spread['nickname'] . '获得:' . $team_level['title'] . '管理奖' . $team_brokerage);

										//检测是否存在比二级等级高的上线存在,如存在则计算更高等级的管理奖
										$this->getTeamBroerage($uid, $level, $index);
									} else if ($two_spread->m_level < $one_spread->m_level) {
										$index = array_search($one_spread->m_level, array_column($level, 'grade'));
										//存在比一级等级高的上线获得管理奖
										$this->getTeamBroerage($uid, $level, $index);
									}
								}
							}

						}

					}

				}

			}
		}

		/**
		 * 1.佣金的算法: 获取对应等级的 一级 二级佣金
		 * 2.团队管理奖：下单价 - 上级价
		 *
		 *
		 */

	}


	protected function getSpeciCount ($data, $one, $level) {
		$uid = array_column($data, 'uid');
		$index = array_search($one['uid'], $uid);
		$spread_count = [];
		$m_level_count = [];
		for ($i = 0; $i < $index; $i++) {
			$spread_count[] = $data[$i];
			if ($data[$i]['o_m_level'] === $level) {
				$m_level_count[] = $data[$i];
			}
		}

		return count($spread_count) === count($m_level_count) ? true : false;

	}


	/**
	 * 检测是否存在比指定用户等级高的上线,如存在则计算管理奖
	 *
	 * @param     $uid
	 * @param     $level
	 * @param int $i
	 * @param
	 *
	 * @throws
	 *
	 */
	protected function getTeamBroerage ($uid, $level, $i = 0) {
		$price = 100;
		$index = intval($i + 1);
		if (array_key_exists($index, $level)) {//存在如,现在是分销商，则存在一个团队
			//获得团队1的等级，获得指定等级的上线
			$team_level = $level[$index];
			$this->getAllSpread($uid, $team, $team_level['grade']);
			if ($team) {
				$team_brokerage = bcmul($price, bcdiv($team_level['team_ratio'], 100, 2), 2);
				addErrorLog($team['nickname'] . '获得:' . $team_level['title'] . '管理奖' . $team_brokerage);
			}

			$index = intval($i + 2);
			if (array_key_exists($index, $level)) {//存在如,现在是分销商，则存在一个团队
				$team_level = $level[$index];
				$this->getAllSpread($uid, $team, $team_level['grade']);
				if ($team) {
					$team_brokerage = bcmul($price, bcdiv($team_level['team_ratio'], 100, 2), 2);
					addErrorLog($team['nickname'] . '获得:' . $team_level['title'] . '管理奖' . $team_brokerage);
				}
			}
		}

	}


	/**
	 * @param      $uid
	 * @param      $data $level 存在是是一维数组即可,不存在时使用二维数组
	 * @param null $level
	 *
	 * @param
	 *
	 * @return array|\think\Model|null
	 * @throws
	 *
	 */
	public function getAllSpread ($uid, &$data, $level = 0) {
		$item = User::where('uid', ' = ', $uid)->field('uid,nickname,spread_uid,o_m_level,m_level')->find();

		if ($item && $item->spread_uid) {
			$spread = User::where('uid', ' = ', $item->spread_uid)->field('uid,nickname,spread_uid,o_m_level,m_level')->find();
			if ($spread) {
				if ($level) {//存在要获取指定等级第一个用户
					if ($spread->m_level === $level) {//存在该等级的,返回
						$data = $spread->toArray();
					} else {//不存在的继续往上找
						$this->getAllSpread($spread->uid, $data, $level);
					}
				} else {
					$data[] = $spread->toArray();
					$this->getAllSpread($spread->uid, $data);
				}
			}
		}

		return $data;
	}


	public function getAllSubordinate ($uid, &$data) {
		$list = User::where('spread_uid', ' = ', $uid)->field('uid,nickname,spread_uid,o_m_level')->select();

		if ($list && $list = $list->toArray()) {
			foreach ($list as $li) {
				$data[] = $li;
				$this->getAllSubordinate($li['uid'], $data);
			}
		}

		return $data;
	}


	public function a ($uid, $level, $i = 0) {
		static $array = [];
		if (empty($i)) {
			$array = [];
		}
		$item = User::where('uid', ' = ', $uid)->field('uid,nickname,spread_uid,o_m_level')->find();
		if ($item && $item->spread_uid) {
			$spread = User::where('uid', ' = ', $item->spread_uid)->field('uid,nickname,spread_uid,o_m_level')->find();
			if ($spread) {
				$i++;
				$array[] = $spread->toArray();
				if ($spread->uid) {
					$this->a($spread->uid, $level, $i);
				}
			}
		}
		$a = null;

		if ($array) {
			foreach ($array as $value) {
				if ($value['o_m_level'] === $level) {
					$a = $value;
					break;
				}
			}
		}

		return $a;

	}

	public function b ($uid, $level, &$data) {

		$item = User::where('uid', ' = ', $uid)->field('uid,nickname,spread_uid,o_m_level')->find();
		if ($item && $item->spread_uid) {
			$spread = User::where('uid', ' = ', $item->spread_uid)->field('uid,nickname,spread_uid,o_m_level')->find();

			if ($spread && $spread->o_m_level == $level) {//取出第一个
				$data = $spread->toArray();
			} else {
				$this->b($spread->uid, $level, $data);
			}
		}

		return $data;
	}


	public function c ($uid, &$data) {
		$item = User::where('uid', ' = ', $uid)->field('uid,nickname,spread_uid,o_m_level')->find();
		if ($item && $item->spread_uid) {
			$spread = User::where('uid', ' = ', $item->spread_uid)->field('uid,nickname,spread_uid,o_m_level')->find();
			if ($spread) {
				$data[] = $spread->toArray();
				if ($spread->uid) {
					$this->c($spread->uid, $data);
				}
			}
		}

		return $data;
	}


	/**
	 * @param      $array           数组
	 * @param      $element         元素
	 * @param      $condition       条件
	 * @param bool $index           获取元素在数组中的下标
	 *
	 * @param
	 *
	 * @return mixed
	 * @throws
	 *
	 */
	public function getElement ($array, $element, $condition, $index = false) {
		$arr = array_filter($array, function ($item) use ($element, $condition) {
			return $item[$element] == $condition;
		});

		if ($index) {
			return current(array_keys($arr));
		}

		return current($arr);
	}


}

//
